`timescale 1ns / 1ps

module try_xpmRam();

parameter A_WIDTH_A = 4;
parameter D_WIDTH_A = 8;
parameter A_WIDTH_B = 4;
parameter D_WIDTH_B = 8;
localparam MEM_SIZE = (1 << A_WIDTH_A) * D_WIDTH_A;

reg         clk;
reg         rst;
reg         en_a;
reg         en_b;
reg  [A_WIDTH_A-1:0]  addr_a;
reg  [A_WIDTH_B-1:0]  addr_b;
reg  [D_WIDTH_A-1:0]  din;
wire [D_WIDTH_B-1:0]  dout;

always #5 clk = ~clk;

integer i;
initial
begin
    clk = 0;
    rst = 1;
    #20;
    rst = 0;
    #10;
    for (i = 0; i < 16; i = i + 1) begin
        // en_a = 0;
        // dice = {$random()} % 3;
        // for (j = 0; j < dice; j = j + 1) begin
        //     #10;
        // end
        din = i * i;
        addr_a = i;
        en_a = 1;
        # 10;
    end
    din = 0;
    en_a = 0;
    addr_a = 0;
    # 10;
    for (i = 0; i < 16; i = i + 1) begin
        addr_b = i;
        en_b = 1;
        # 10;
    end
    addr_b = 0;
    en_b = 0;
    # 50;
    $display("Done.");
    $stop;
end


xpm_memory_sdpram #(
   .ADDR_WIDTH_A            (A_WIDTH_A),                // DECIMAL
   .ADDR_WIDTH_B            (A_WIDTH_B),                // DECIMAL
   .AUTO_SLEEP_TIME         (0),                        // DECIMAL
   .BYTE_WRITE_WIDTH_A      (D_WIDTH_A),                // DECIMAL
   .CLOCKING_MODE           ("common_clock"),           // String
   .ECC_MODE                ("no_ecc"),                 // String
   .MEMORY_INIT_FILE        ("none"),                   // String
   .MEMORY_INIT_PARAM       ("0"),                      // String
   .MEMORY_OPTIMIZATION     ("true"),                   // String
   .MEMORY_PRIMITIVE        ("distributed"),            // String
   .MEMORY_SIZE             (MEM_SIZE),                 // DECIMAL
   .MESSAGE_CONTROL         (1),                        // DECIMAL
   .READ_DATA_WIDTH_B       (D_WIDTH_B),                // DECIMAL
   .READ_LATENCY_B          (2),                        // DECIMAL
   .READ_RESET_VALUE_B      ("0"),                      // String
   .USE_EMBEDDED_CONSTRAINT (0),                        // DECIMAL
   .USE_MEM_INIT            (1),                        // DECIMAL
   .WAKEUP_TIME             ("disable_sleep"),          // String
   .WRITE_DATA_WIDTH_A      (D_WIDTH_A),                // DECIMAL
   .WRITE_MODE_B            ("read_first")              // String
)
xpm_memory_sdpram_inst (
   .dbiterrb(),                     // 1-bit output: Status signal to indicate double bit error occurrence
                                    // on the data output of port B.

   .doutb(dout),                    // READ_DATA_WIDTH_B-bit output: Data output for port B read operations.
   .sbiterrb(),                     // 1-bit output: Status signal to indicate single bit error occurrence
                                    // on the data output of port B.

   .addra(addr_a),                  // ADDR_WIDTH_A-bit input: Address for port A write operations.
   .addrb(addr_b),                  // ADDR_WIDTH_B-bit input: Address for port B read operations.
   .clka(clk),                      // 1-bit input: Clock signal for port A. Also clocks port B when
                                    // parameter CLOCKING_MODE is "common_clock".

   .clkb(1'b0),                     // 1-bit input: Clock signal for port B when parameter CLOCKING_MODE is
                                    // "independent_clock". Unused when parameter CLOCKING_MODE is
                                    // "common_clock".

   .dina(din),                      // WRITE_DATA_WIDTH_A-bit input: Data input for port A write operations.
   .ena(en_a),                      // 1-bit input: Memory enable signal for port A. Must be high on clock
                                    // cycles when write operations are initiated. Pipelined internally.

   .enb(en_b),                      // 1-bit input: Memory enable signal for port B. Must be high on clock
                                    // cycles when read operations are initiated. Pipelined internally.

   .injectdbiterra(1'b0),           // 1-bit input: Controls double bit error injection on input data when
                                    // ECC enabled (Error injection capability is not available in
                                    // "decode_only" mode).

   .injectsbiterra(1'b0),           // 1-bit input: Controls single bit error injection on input data when
                                    // ECC enabled (Error injection capability is not available in
                                    // "decode_only" mode).

   .regceb(1'b1),                   // 1-bit input: Clock Enable for the last register stage on the output
                                    // data path.

   .rstb(rst),                      // 1-bit input: Reset signal for the final port B output register stage.
                                    // Synchronously resets output port doutb to the value specified by
                                    // parameter READ_RESET_VALUE_B.

   .sleep(1'b0),                    // 1-bit input: sleep signal to enable the dynamic power saving feature.
   .wea(en_a)                       // WRITE_DATA_WIDTH_A-bit input: Write enable vector for port A input
                                    // data port dina. 1 bit wide when word-wide writes are used. In
                                    // byte-wide write configurations, each bit controls the writing one
                                    // byte of dina to address addra. For example, to synchronously write
                                    // only bits [15-8] of dina when WRITE_DATA_WIDTH_A is 32, wea would be
                                    // 4'b0010.

);

endmodule
